
// Copyright (C) 2009-2011 Luca Piccioni
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//   
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

using Derm.OpenGL;
using Derm.Render;

namespace Derm
{
	#region Generic Vertex

	/// <summary>
	/// Base type of vertex components.
	/// </summary>
	public enum VertexBaseType
	{
		/// <summary>
		/// Signed byte components.
		/// </summary>
		Byte = Gl.BYTE,
		/// <summary>
		/// Unsigned byte components.
		/// </summary>
		UByte = Gl.UNSIGNED_BYTE,
		/// <summary>
		/// Signed short components.
		/// </summary>
		Short = Gl.SHORT,
		/// <summary>
		/// Unsigned short components.
		/// </summary>
		UShort = Gl.UNSIGNED_SHORT,
		/// <summary>
		/// Signed integer components.
		/// </summary>
		Int = Gl.INT,
		/// <summary>
		/// Unsigned integer components.
		/// </summary>
		UInt = Gl.UNSIGNED_INT,
		/// <summary>
		/// Single-precision floating-point components.
		/// </summary>
		Float = Gl.FLOAT,
		/// <summary>
		/// Double-precision floating-point components.
		/// </summary>
		Double = Gl.DOUBLE,
		/// <summary>
		/// Half-precision floating-point components.
		/// </summary>
		Half = Gl.HALF_FLOAT,

		/// <summary>
		/// Value internally used for indicating an undefined vertex array base type.
		/// </summary>
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		Undefined
	}
	
	/// <summary>
	/// Generic vertex interface.
	/// </summary>
	public interface IVertex : IXmlSerializable
	{
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		float this[int idx] { get; set; }
	}
	
	#endregion
	
	#region Bidimensional Vertex
	
	/// <summary>
	/// Generic bidimensional vertex interface.
	/// </summary>
	public interface IVertex2 : IVertex
	{
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		float X { get; set; }
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		float Y { get; set; }
	}
	
	/// <summary>
	/// Bidimensional vertex value type (byte coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.UByte, 2)]
	public struct Vertex2b : IVertex2
	{
		#region Structure
		
		/// <summary>
		/// X coordinate for bidimensional vertex.
		/// </summary>
		public byte x;

		/// <summary>
		/// Y coordinate for bidimensional vertex.
		/// </summary>
		public byte y;
		
		#endregion
		
		#region IVertex2 Implementation
		
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((byte)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((byte)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion
		
		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Bidimensional vertex value type (short coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Short, 2)]
	public struct Vertex2s : IVertex2
	{
		#region Structure

		/// <summary>
		/// X coordinate for bidimensional vertex.
		/// </summary>
		public short x;

		/// <summary>
		/// Y coordinate for bidimensional vertex.
		/// </summary>
		public short y;

		#endregion

		#region IVertex2 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((short)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((short)value); }
		}

		#endregion

		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Bidimensional vertex value type (integer coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Int, 2)]
	public struct Vertex2i : IVertex2
	{
		#region Constructors

		/// <summary>
		/// Constructor a bidimensional vertex using coordinates.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex2i(int x, int y)
		{
			this.x = x;
			this.y = y;
		}
		
		/// <summary>
		/// Constructor a bidimensional vertex using coordinate array.
		/// </summary>
		/// <param name="v">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex2i(int[] v) : this(v[0], v[1])
		{
			
		}

		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for bidimensional vertex.
		/// </summary>
		public int x;

		/// <summary>
		/// Y coordinate for bidimensional vertex.
		/// </summary>
		public int y;

		#endregion

		#region IVertex2 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((int)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((int)value); }
		}
		
		#endregion

		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Bidimensional vertex value type (float coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexArrayType.Vec2)]
	public struct Vertex2f : IVertex2
	{
		#region Constructors
		
		/// <summary>
		/// Vertex2f constructor.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex2f(float x, float y)
		{
			this.x = x;
			this.y = y;
		}
		
		/// <summary>
		/// Vertex2f constructor.
		/// </summary>
		/// <param name="v">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex2f(float[] v) :
			this(v[0], v[1])
		{
			
		}

		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for bidimensional vertex.
		/// </summary>
		public float x;
		/// <summary>
		/// Y coordinate for bidimensional vertex.
		/// </summary>
		public float y;
		
		#endregion
		
		#region Operator Overloading

		/// <summary>
		/// Negate operator
		/// </summary>
		/// <param name="v1">
		/// </param>
		/// <returns>
		/// It returns the negate of <paramref name="v1"/>.
		/// </returns>
		public static Vertex2f operator -(Vertex2f v1)
		{
			Vertex2f v;

			v.x = -v1.x;
			v.y = -v1.y;

			return (v);
		}
		
		/// <summary>
		/// Add operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex2f operator +(Vertex2f v1, Vertex2f v2)
		{
			Vertex2f v;
			
			v.x = v1.x + v2.x;
			v.y = v1.y + v2.y;
			
			return (v);
		}
		
		/// <summary>
		/// Subtract operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex2f operator -(Vertex2f v1, Vertex2f v2)
		{
			Vertex2f v;
			
			v.x = v1.x - v2.x;
			v.y = v1.y - v2.y;
			
			return (v);
		}

		/// <summary>
		/// Scalar multiply operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex2f operator *(Vertex2f v1, float scalar)
		{
			Vertex2f v;
			
			v.x = v1.x * scalar;
			v.y = v1.y * scalar;
			
			return (v);
		}

		/// <summary>
		/// Scalar divide operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex2f operator /(Vertex2f v1, float scalar)
		{
			Vertex2f v;
			
			v.x = v1.x / scalar;
			v.y = v1.y / scalar;
			
			return (v);
		}
		
		#endregion
		
		#region Vertex Methods

		/// <summary>
		/// Compute bidimensional vertex module.
		/// </summary>
		/// <returns>It returns the vertex vector module.</returns>
		public float Module()
		{
			float x2 = (x * y);
			float y2 = (x * y);

			return ((float)Math.Sqrt(x2 + y2));
		}

		/// <summary>
		/// Normalize vertex coordinates.
		/// </summary>
		public void Normalize()
		{
			this /= Module();
		}

		#endregion

		#region Cast

		/// <summary>
		/// Cast to float[] operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator float[](Vertex2f a)
		{
			float[] v = new float[2];

			v[0] = a.x;
			v[1] = a.y;

			return (v);
		}
		
		/// <summary>
		/// Cast to Vertex3d operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator Vertex2d(Vertex2f a)
		{
			Vertex2d v;

			v.x = a.x;
			v.y = a.y;

			return (v);
		}
		
		/// <summary>
		/// Cast to Vertex2f operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static explicit operator Vertex3f(Vertex2f a)
		{
			Vertex3f v;
			
			v.x = a.x;
			v.y = a.y;
			v.z = 0.0f;
			
			return (v);
		}
		
		#endregion

		#region IVertex2 Implementation
		
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = value; }
		}
		
		#endregion

		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Bidimensional vertex value type (double coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexArrayType.DoubleVec2)]
	public struct Vertex2d : IVertex2
	{
		#region Structure

		/// <summary>
		/// X coordinate for bidimensional vertex.
		/// </summary>
		public double x;
		/// <summary>
		/// Y coordinate for bidimensional vertex.
		/// </summary>
		public double y;

		#endregion

		#region IVertex2 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return ((float)x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return ((float)y); }
			set { y = value; }
		}
		
		#endregion

		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex2 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	#endregion
	
	#region Tridimensional Vertex
	
	/// <summary>
	/// Generic tridimensional vertex interface.
	/// </summary>
	public interface IVertex3 : IVertex
	{
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		float X { get; set; }
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		float Y { get; set; }
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		float Z { get; set; }
	}
	
	/// <summary>
	/// Tridimensional vertex value type (byte coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.UByte, 3)]
	public struct Vertex3b : IVertex3, IEquatable<IVertex3>
	{
		#region Structure

		/// <summary>
		/// X coordinate for tridimensional vertex.
		/// </summary>
		public byte x;

		/// <summary>
		/// Y coordinate for tridimensional vertex.
		/// </summary>
		public byte y;

		/// <summary>
		/// Z coordinate for tridimensional vertex.
		/// </summary>
		public byte z;

		#endregion

		#region Equality Operators

		/// <summary>
		/// Equality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator==(Vertex3b v1, Vertex3b v2)
		{
			return (v1.Equals(v2));
		}

		/// <summary>
		/// Inequality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator!=(Vertex3b v1, Vertex3b v2)
		{
			return (!v1.Equals(v2));
		}

		#endregion

		#region IVertex3 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((byte)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = (byte)value; }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((byte)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IEquatable<IVertex3> Implementation

		/// <summary>
		/// Indicates whether the this Matrix is equal to another Matrix.
		/// </summary>
		/// <param name="other">
		/// A Matrix to compare with this object.
		/// </param>
		/// <returns>
		/// It returns true if the this Matrix is equal to <paramref name="other"/>; otherwise, false.
		/// </returns>
		public bool Equals(IVertex3 other)
		{
			if (ReferenceEquals(null, other))
				return false;
			
			if (Math.Abs(X - other.X) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Y - other.Y) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Z - other.Z) >= Single.Epsilon)
				return (false);

			return (true);
		}

		/// <summary>
		/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <param name="obj">
		/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
		/// </param>
		/// <returns>
		/// It returns true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj))
				return false;
			if (obj.GetType() != typeof(IVertex3))
				return false;

			return (Equals((IVertex3)obj));
		}

		/// <summary>
		/// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"/> is suitable for
		/// use in hashing algorithms and data structures like a hash table.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked {
				int result;

				result = X.GetHashCode();
				result = (result * 397) ^ Y.GetHashCode();
				result = (result * 397) ^ Z.GetHashCode();

				return result;
			}
		}

		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// An System.Xml.Schema.XmlSchema that describes the XML representation of the object that is produced by the
		/// System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter) method and consumed by the
		/// System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader) method.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Tridimensional vertex value type (short coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Short, 3)]
	public struct Vertex3s : IVertex3, IEquatable<IVertex3>
	{
		#region Structure

		/// <summary>
		/// X coordinate for tridimensional vertex.
		/// </summary>
		public short x;
		/// <summary>
		/// Y coordinate for tridimensional vertex.
		/// </summary>
		public short y;
		/// <summary>
		/// Z coordinate for tridimensional vertex.
		/// </summary>
		public short z;

		#endregion

		#region Equality Operators

		/// <summary>
		/// Equality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator==(Vertex3s v1, Vertex3s v2)
		{
			return (v1.Equals(v2));
		}

		/// <summary>
		/// Inequality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator!=(Vertex3s v1, Vertex3s v2)
		{
			return (!v1.Equals(v2));
		}

		#endregion

		#region IVertex3 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((short)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((short)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((short)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IEquatable<IVertex3> Implementation

		/// <summary>
		/// Indicates whether the this Matrix is equal to another Matrix.
		/// </summary>
		/// <param name="other">
		/// A Matrix to compare with this object.
		/// </param>
		/// <returns>
		/// It returns true if the this Matrix is equal to <paramref name="other"/>; otherwise, false.
		/// </returns>
		public bool Equals(IVertex3 other)
		{
			if (ReferenceEquals(null, other))
				return false;
			
			if (Math.Abs(X - other.X) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Y - other.Y) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Z - other.Z) >= Single.Epsilon)
				return (false);

			return (true);
		}

		/// <summary>
		/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <param name="obj">
		/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
		/// </param>
		/// <returns>
		/// It returns true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj))
				return false;
			if (obj.GetType() != typeof(IVertex3))
				return false;

			return (Equals((IVertex3)obj));
		}

		/// <summary>
		/// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"/> is suitable for
		/// use in hashing algorithms and data structures like a hash table.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked {
				int result;

				result = X.GetHashCode();
				result = (result * 397) ^ Y.GetHashCode();
				result = (result * 397) ^ Z.GetHashCode();

				return result;
			}
		}

		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// An System.Xml.Schema.XmlSchema that describes the XML representation of the object that is produced by the
		/// System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter) method and consumed by the
		/// System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader) method.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Tridimensional vertex value type (integer coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Int, 3)]
	public struct Vertex3i : IVertex3, IEquatable<IVertex3>
	{
		#region Constructors
		
		/// <summary>
		/// Vertex3i constructor.
		/// </summary>
		/// <param name="v">
		/// A <see cref="System.Int32"/>
		/// </param>
		public Vertex3i(int[] v) : this(v[0], v[1], v[2])
		{
			
		}
		
		/// <summary>
		/// Vertex3i constructor.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Int32"/>
		/// </param>
		public Vertex3i(int x, int y, int z)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}

		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for tridimensional vertex.
		/// </summary>
		public int x;
		/// <summary>
		/// Y coordinate for tridimensional vertex.
		/// </summary>
		public int y;
		/// <summary>
		/// Z coordinate for tridimensional vertex.
		/// </summary>
		public int z;
		
		#endregion

		#region Equality Operators

		/// <summary>
		/// Equality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator==(Vertex3i v1, Vertex3i v2)
		{
			return (v1.Equals(v2));
		}

		/// <summary>
		/// Inequality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator!=(Vertex3i v1, Vertex3i v2)
		{
			return (!v1.Equals(v2));
		}

		#endregion
		
		#region IVertex3 Implementation
		
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((int)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((int)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((int)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IEquatable<IVertex3> Implementation

		/// <summary>
		/// Indicates whether the this Matrix is equal to another Matrix.
		/// </summary>
		/// <param name="other">
		/// A Matrix to compare with this object.
		/// </param>
		/// <returns>
		/// It returns true if the this Matrix is equal to <paramref name="other"/>; otherwise, false.
		/// </returns>
		public bool Equals(IVertex3 other)
		{
			if (ReferenceEquals(null, other))
				return false;
			
			if (Math.Abs(X - other.X) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Y - other.Y) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Z - other.Z) >= Single.Epsilon)
				return (false);

			return (true);
		}

		/// <summary>
		/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <param name="obj">
		/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
		/// </param>
		/// <returns>
		/// It returns true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj))
				return false;
			if (obj.GetType() != typeof(IVertex3))
				return false;

			return (Equals((IVertex3)obj));
		}

		/// <summary>
		/// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"/> is suitable for
		/// use in hashing algorithms and data structures like a hash table.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked {
				int result;

				result = X.GetHashCode();
				result = (result * 397) ^ Y.GetHashCode();
				result = (result * 397) ^ Z.GetHashCode();

				return result;
			}
		}

		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// An System.Xml.Schema.XmlSchema that describes the XML representation of the object that is produced by the
		/// System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter) method and consumed by the
		/// System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader) method.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Tridimensional vertex value type (float coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Float, 3)]
	public struct Vertex3f : IVertex3, IEquatable<IVertex3>
	{
		#region Constructors
		
		/// <summary>
		/// Vertex3f constructor.
		/// </summary>
		/// <param name="v">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex3f(float[] v) : this(v[0], v[1], v[2])
		{
			
		}
		
		/// <summary>
		/// Vertex3f constructor.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex3f(float x, float y, float z)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}

		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for tridimensional vertex.
		/// </summary>
		public float x;

		/// <summary>
		/// Y coordinate for tridimensional vertex.
		/// </summary>
		public float y;

		/// <summary>
		/// Z coordinate for tridimensional vertex.
		/// </summary>
		public float z;
		
		#endregion
		
		#region Arithmetic Operators

		/// <summary>
		/// Negate operator.
		/// </summary>
		/// <param name="v1">
		/// </param>
		/// <returns>
		/// It returns the negate of <paramref name="v1"/>.
		/// </returns>
		public static Vertex3f operator -(Vertex3f v1)
		{
			Vertex3f v;

			v.x = -v1.x;
			v.y = -v1.y;
			v.z = -v1.z;

			return (v);
		}
		
		/// <summary>
		/// Add operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3f operator +(Vertex3f v1, Vertex3f v2)
		{
			Vertex3f v;
			
			v.x = v1.x + v2.x;
			v.y = v1.y + v2.y;
			v.z = v1.z + v2.z;
			
			return (v);
		}
		
		/// <summary>
		/// Subtract operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3f operator -(Vertex3f v1, Vertex3f v2)
		{
			Vertex3f v;
			
			v.x = v1.x - v2.x;
			v.y = v1.y - v2.y;
			v.z = v1.z - v2.z;
			
			return (v);
		}

		/// <summary>
		/// Scalar multiply operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3f operator *(Vertex3f v1, float scalar)
		{
			Vertex3f v;
			
			v.x = v1.x * scalar;
			v.y = v1.y * scalar;
			v.z = v1.z * scalar;
			
			return (v);
		}

		/// <summary>
		/// Scalar divide operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex3f operator /(Vertex3f v1, float scalar)
		{
			Vertex3f v;
			
			v.x = v1.x / scalar;
			v.y = v1.y / scalar;
			v.z = v1.z / scalar;
			
			return (v);
		}
		
		/// <summary>
		/// Dot product operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/> representing the left dot product operand.
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/> representing the right dot product operand.
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/> representing the dot product between <paramref name="v1"/> and
		/// <paramref name="v2"/>.
		/// </returns>
		public static float operator *(Vertex3f v1, Vertex3f v2)
		{
			return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
		}
		
		/// <summary>
		/// Cross product operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/> representing the left cross product operand.
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/> representing the right cross product operand.
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/> representing the cross product between <paramref name="v1"/> and
		/// <paramref name="v2"/>.
		/// </returns>
		public static Vertex3f operator ^(Vertex3f v1, Vertex3f v2)
		{
			Vertex3f v;
			
			v.x = v1.y * v2.z - v1.z * v2.y;
			v.y = v1.z * v2.x - v1.x * v2.z;
			v.z = v1.x * v2.y - v1.y * v2.x;
			
			return (v);
		}

		/// <summary>
		/// Vertex and matrix multiplication.
		/// </summary>
		/// <param name="v">
		/// A <see cref="Vertex3f"/> representing the vertex to be transformed.
		/// </param>
		/// <param name="m">
		/// A <see cref="Matrix4x4"/> representing the transformation matrix.
		/// </param>
		/// <returns>
		/// It returns a <see cref="Vertex3f"/> which represents the transformed vertex.
		/// </returns>
		public static Vertex3f operator *(Vertex3f v, Matrix4x4 m)
		{
			Vertex3f r;

			r.x = (v.x * m[0,0]) + (v.y * m[0,1]) + (v.z * m[0,2]) + m[0,3];
			r.y = (v.x * m[1,1]) + (v.y * m[1,1]) + (v.z * m[1,2]) + m[1,3];
			r.z = (v.x * m[2,2]) + (v.y * m[2,1]) + (v.z * m[2,2]) + m[2,3];

			return (r);
		}
		
		#endregion

		#region Equality Operators

		/// <summary>
		/// Equality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator==(Vertex3f v1, Vertex3f v2)
		{
			return (v1.Equals(v2));
		}

		/// <summary>
		/// Inequality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator!=(Vertex3f v1, Vertex3f v2)
		{
			return (!v1.Equals(v2));
		}

		#endregion

		#region Cast Operators

		/// <summary>
		/// Cast to float[] operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator float[](Vertex3f a)
		{
			float[] v = new float[3];

			v[0] = a.x;
			v[1] = a.y;
			v[2] = a.z;

			return (v);
		}

		/// <summary>
		/// Cast to Vertex2f operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static explicit operator Vertex2f(Vertex3f a)
		{
			Vertex2f v;
			
			v.x = a.x;
			v.y = a.y;
			
			return (v);
		}

		/// <summary>
		/// Cast to Vertex4f operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static explicit operator Vertex4f(Vertex3f a)
		{
			Vertex4f v;

			v.x = a.x;
			v.y = a.y;
			v.z = a.z;
			v.w = 1.0f;

			return (v);
		}
		
		/// <summary>
		/// Cast to Vertex3d operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator Vertex3d(Vertex3f a)
		{
			Vertex3d v;

			v.x = a.x;
			v.y = a.y;
			v.z = a.z;

			return (v);
		}

		/// <summary>
		/// Cast to Vertex3d operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator ColorRGBAF(Vertex3f a)
		{
			return (new ColorRGBAF(a.x, a.y, a.z, 1.0f));
		}
		
		#endregion
		
		#region Vertex Methods

		/// <summary>
		/// Compute bidimensional vertex module.
		/// </summary>
		/// <returns>It returns the vertex vector module.</returns>
		public float Module()
		{
			float x2 = (x * x);
			float y2 = (y * y);
			float z2 = (z * z);

			return ((float)Math.Sqrt(x2 + y2 + z2));
		}

		/// <summary>
		/// Normalize vertex coordinates.
		/// </summary>
		public void Normalize()
		{
			this /= Module();
		}

		#endregion

		#region Notable Vertex

		/// <summary>
		/// Origin vertex.
		/// </summary>
		public static readonly Vertex3f Zero = new Vertex3f(0.0f, 0.0f, 0.0f);

		/// <summary>
		/// Unit vertex along X axis.
		/// </summary>
		public static readonly Vertex3f UnitX = new Vertex3f(1.0f, 0.0f, 0.0f);

		/// <summary>
		/// Unit vertex along Y axis.
		/// </summary>
		public static readonly Vertex3f UnitY = new Vertex3f(0.0f, 1.0f, 0.0f);

		/// <summary>
		/// Unit vertex along Z axis.
		/// </summary>
		public static readonly Vertex3f UnitZ = new Vertex3f(0.0f, 0.0f, 1.0f);

		#endregion

		#region IVertex3 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = value; }
		}

		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IEquatable<IVertex3> Implementation

		/// <summary>
		/// Indicates whether the this Matrix is equal to another Matrix.
		/// </summary>
		/// <param name="other">
		/// A Matrix to compare with this object.
		/// </param>
		/// <returns>
		/// It returns true if the this Matrix is equal to <paramref name="other"/>; otherwise, false.
		/// </returns>
		public bool Equals(IVertex3 other)
		{
			if (ReferenceEquals(null, other))
				return false;
			
			if (Math.Abs(X - other.X) >= 1e-6f)
				return (false);
			if (Math.Abs(Y - other.Y) >= 1e-6f)
				return (false);
			if (Math.Abs(Z - other.Z) >= 1e-6f)
				return (false);

			return (true);
		}

		/// <summary>
		/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <param name="obj">
		/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
		/// </param>
		/// <returns>
		/// It returns true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj))
				return (false);
			if (obj.GetType().GetInterface("IVertex") == null)
				return (false);

			return (Equals((IVertex3)obj));
		}

		/// <summary>
		/// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"/> is suitable for
		/// use in hashing algorithms and data structures like a hash table.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked {
				int result;

				result = X.GetHashCode();
				result = (result * 397) ^ Y.GetHashCode();
				result = (result * 397) ^ Z.GetHashCode();

				return result;
			}
		}

		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// An System.Xml.Schema.XmlSchema that describes the XML representation of the object that is produced by the
		/// System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter) method and consumed by the
		/// System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader) method.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion

		#region Object Overrides

		/// <summary>
		/// Stringify this Vertex3f.
		/// </summary>
		/// <returns>
		/// Returns a <see cref="System.String"/> that represents this Vertex3f.
		/// </returns>
		public override string ToString()
		{
			return (String.Format("|{0}, {1}, {2}|", x, y, z));
		}

		#endregion
	}
	
	/// <summary>
	/// Tridimensional vertex value type (double coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Double, 3)]
	public struct Vertex3d : IVertex3, IEquatable<IVertex3>
	{
		#region Constructors
		
		/// <summary>
		/// Vertex3d constructor.
		/// </summary>
		/// <param name="v">
		/// A <see cref="System.Double"/>
		/// </param>
		public Vertex3d(double[] v) : this(v[0], v[1], v[2])
		{
			
		}
		
		/// <summary>
		/// Vertex3d constructor.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex3d(double x, double y, double z)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for tridimensional vertex.
		/// </summary>
		public double x;

		/// <summary>
		/// Y coordinate for tridimensional vertex.
		/// </summary>
		public double y;

		/// <summary>
		/// Z coordinate for tridimensional vertex.
		/// </summary>
		public double z;

		#endregion

		#region Arithmetic Operators

		/// <summary>
		/// Negate operator.
		/// </summary>
		/// <param name="v1">
		/// </param>
		/// <returns>
		/// It returns the negate of <paramref name="v1"/>.
		/// </returns>
		public static Vertex3d operator -(Vertex3d v1)
		{
			Vertex3d v;

			v.x = -v1.x;
			v.y = -v1.y;
			v.z = -v1.z;

			return (v);
		}
		
		/// <summary>
		/// Add operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3d operator +(Vertex3d v1, Vertex3d v2)
		{
			Vertex3d v;
			
			v.x = v1.x + v2.x;
			v.y = v1.y + v2.y;
			v.z = v1.z + v2.z;
			
			return (v);
		}
		
		/// <summary>
		/// Subtract operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3d operator -(Vertex3d v1, Vertex3d v2)
		{
			Vertex3d v;
			
			v.x = v1.x - v2.x;
			v.y = v1.y - v2.y;
			v.z = v1.z - v2.z;
			
			return (v);
		}

		/// <summary>
		/// Scalar multiply operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/>
		/// </returns>
		public static Vertex3d operator *(Vertex3d v1, double scalar)
		{
			Vertex3d v;
			
			v.x = v1.x * scalar;
			v.y = v1.y * scalar;
			v.z = v1.z * scalar;
			
			return (v);
		}

		/// <summary>
		/// Scalar divide operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex2f"/>
		/// </param>
		/// <param name="scalar">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static Vertex3d operator /(Vertex3d v1, double scalar)
		{
			Vertex3d v;
			
			v.x = v1.x / scalar;
			v.y = v1.y / scalar;
			v.z = v1.z / scalar;
			
			return (v);
		}
		
		/// <summary>
		/// Dot product operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/> representing the left dot product operand.
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/> representing the right dot product operand.
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/> representing the dot product between <paramref name="v1"/> and
		/// <paramref name="v2"/>.
		/// </returns>
		public static double operator *(Vertex3d v1, Vertex3d v2)
		{
			return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
		}
		
		/// <summary>
		/// Cross product operator.
		/// </summary>
		/// <param name="v1">
		/// A <see cref="Vertex3f"/> representing the left cross product operand.
		/// </param>
		/// <param name="v2">
		/// A <see cref="Vertex3f"/> representing the right cross product operand.
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3f"/> representing the cross product between <paramref name="v1"/> and
		/// <paramref name="v2"/>.
		/// </returns>
		public static Vertex3d operator %(Vertex3d v1, Vertex3d v2)
		{
			Vertex3d v;
			
			v.x = v1.x * v2.z - v1.z * v2.y;
			v.y = v1.z * v2.x - v1.x * v2.z;
			v.z = v1.x * v2.y - v1.y * v2.x;
			
			return (v);
		}

		/// <summary>
		/// Vertex and matrix multiplication.
		/// </summary>
		/// <param name="v">
		/// A <see cref="Vertex3f"/> representing the vertex to be transformed.
		/// </param>
		/// <param name="m">
		/// A <see cref="Matrix4x4"/> representing the transformation matrix.
		/// </param>
		/// <returns>
		/// It returns a <see cref="Vertex3f"/> which represents the transformed vertex.
		/// </returns>
		public static Vertex3d operator *(Vertex3d v, Matrix4x4 m)
		{
			Vertex3d r;

			r.x = (v.x * m[0,0]) + (v.y * m[1,0]) + (v.z * m[2,0]) + m[3,0];
			r.y = (v.x * m[0,1]) + (v.y * m[1,1]) + (v.z * m[2,1]) + m[3,1];
			r.z = (v.x * m[0,2]) + (v.y * m[1,2]) + (v.z * m[2,2]) + m[3,2];

			return (r);
		}
		
		#endregion

		#region Equality Operators

		/// <summary>
		/// Equality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator==(Vertex3d v1, Vertex3d v2)
		{
			return (v1.Equals(v2));
		}

		/// <summary>
		/// Inequality operator.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		public static bool operator!=(Vertex3d v1, Vertex3d v2)
		{
			return (!v1.Equals(v2));
		}

		#endregion

		#region Cast Operators

		/// <summary>
		/// Cast to Vertex3d operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex3d"/>
		/// </returns>
		public static explicit operator Vertex3f(Vertex3d a)
		{
			Vertex3f v;

			v.x = (float)a.x;
			v.y = (float)a.y;
			v.z = (float)a.z;

			return (v);
		}
		
		#endregion

		#region Vertex Methods

		/// <summary>
		/// Compute bidimensional vertex module.
		/// </summary>
		/// <returns>It returns the vertex vector module.</returns>
		public double Module()
		{
			double x2 = (x * x);
			double y2 = (y * y);
			double z2 = (z * z);

			return (Math.Sqrt(x2 + y2 + z2));
		}

		/// <summary>
		/// Normalize vertex coordinates.
		/// </summary>
		public void Normalize()
		{
			this /= Module();
		}

		#endregion

		#region Notable Vertex

		/// <summary>
		/// Unit vertex along X axis.
		/// </summary>
		public static readonly Vertex3d UnitX = new Vertex3d(1.0, 0.0, 0.0);

		/// <summary>
		/// Unit vertex along Y axis.
		/// </summary>
		public static readonly Vertex3d UnitY = new Vertex3d(0.0, 1.0, 0.0);

		/// <summary>
		/// Unit vertex along Z axis.
		/// </summary>
		public static readonly Vertex3d UnitZ = new Vertex3d(0.0, 0.0, 1.0);

		#endregion

		#region IVertex3 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return ((float)x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return ((float)y); }
			set { y = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return ((float)z); }
			set { z = value; }
		}

		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IEquatable<IVertex3> Implementation

		/// <summary>
		/// Indicates whether the this Matrix is equal to another Matrix.
		/// </summary>
		/// <param name="other">
		/// A Matrix to compare with this object.
		/// </param>
		/// <returns>
		/// It returns true if the this Matrix is equal to <paramref name="other"/>; otherwise, false.
		/// </returns>
		public bool Equals(IVertex3 other)
		{
			if (ReferenceEquals(null, other))
				return false;
			
			if (Math.Abs(X - other.X) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Y - other.Y) >= Single.Epsilon)
				return (false);
			if (Math.Abs(Z - other.Z) >= Single.Epsilon)
				return (false);

			return (true);
		}

		/// <summary>
		/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <param name="obj">
		/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
		/// </param>
		/// <returns>
		/// It returns true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj))
				return false;
			if (obj.GetType() != typeof(IVertex3))
				return false;

			return (Equals((IVertex3)obj));
		}

		/// <summary>
		/// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"/> is suitable for
		/// use in hashing algorithms and data structures like a hash table.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked {
				int result;

				result = X.GetHashCode();
				result = (result * 397) ^ Y.GetHashCode();
				result = (result * 397) ^ Z.GetHashCode();

				return result;
			}
		}

		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// An System.Xml.Schema.XmlSchema that describes the XML representation of the object that is produced by the
		/// System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter) method and consumed by the
		/// System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader) method.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex3 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion

		#region Object Overrides

		/// <summary>
		/// Stringify this Vertex3d.
		/// </summary>
		/// <returns>
		/// Returns a <see cref="System.String"/> that represents this Vertex3d.
		/// </returns>
		public override string ToString()
		{
			return (String.Format("|{0}, {1}, {2}|", x, y, z));
		}

		#endregion
	}
	
	#endregion
	
	#region Homogeneous Tridimensional Vertex

	/// <summary>
	/// Generic homogeneous tridimensional vertex interface.
	/// </summary>
	public interface IVertex4 : IVertex3
	{
		/// <summary>
		/// Vertex coordinate W.
		/// </summary>
		float W { get; set; }
	}
	
	/// <summary>
	/// Homogeneous tridimensional vertex value type (byte coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.UByte, 4)]
	public struct Vertex4b : IVertex4
	{
		/// <summary>
		/// X coordinate for fourdimensional vertex.
		/// </summary>
		public byte x;
		/// <summary>
		/// Y coordinate for fourdimensional vertex.
		/// </summary>
		public byte y;
		/// <summary>
		/// Z coordinate for fourdimensional vertex.
		/// </summary>
		public byte z;
		/// <summary>
		/// W coordinate for fourdimensional vertex.
		/// </summary>
		public byte w;

		#region IVertex4 Implementation
		
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((byte)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((byte)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((byte)value); }
		}

		/// <summary>
		/// Vertex coordinate w.
		/// </summary>
		public float W
		{
			get { return (w); }
			set { w = checked((byte)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					case 3:
						return (W);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					case 3:
						W = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Homogeneous tridimensional vertex value type (short coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Short, 4)]
	public struct Vertex4s : IVertex4
	{
		#region Structure

		/// <summary>
		/// X coordinate for fourdimensional vertex.
		/// </summary>
		public short x;

		/// <summary>
		/// Y coordinate for fourdimensional vertex.
		/// </summary>
		public short y;

		/// <summary>
		/// Z coordinate for fourdimensional vertex.
		/// </summary>
		public short z;

		/// <summary>
		/// W coordinate for fourdimensional vertex.
		/// </summary>
		public short w;

		#endregion

		#region IVertex4 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((short)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((short)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((short)value); }
		}

		/// <summary>
		/// Vertex coordinate w.
		/// </summary>
		public float W
		{
			get { return (w); }
			set { w = checked((short)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					case 3:
						return (W);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					case 3:
						W = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Homogeneous tridimensional vertex value type (integer coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Int, 4)]
	public struct Vertex4i : IVertex4
	{
		#region Structure

		/// <summary>
		/// X coordinate for fourdimensional vertex.
		/// </summary>
		public int x;

		/// <summary>
		/// Y coordinate for fourdimensional vertex.
		/// </summary>
		public int y;

		/// <summary>
		/// Z coordinate for fourdimensional vertex.
		/// </summary>
		public int z;

		/// <summary>
		/// W coordinate for fourdimensional vertex.
		/// </summary>
		public int w;

		#endregion

		#region IVertex4 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = checked((int)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = checked((int)value); }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = checked((int)value); }
		}

		/// <summary>
		/// Vertex coordinate w.
		/// </summary>
		public float W
		{
			get { return (w); }
			set { w = checked((int)value); }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					case 3:
						return (W);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					case 3:
						W = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	/// <summary>
	/// Homogeneous tridimensional vertex value type (float coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Float, 4)]
	public struct Vertex4f : IVertex4
	{
		#region Constructors
		
		/// <summary>
		/// Vertex3f constructor.
		/// </summary>
		/// <param name="v">
		/// A an array of values that specifies the vertex components.
		/// </param>
		public Vertex4f(float[] v) : this(v[0], v[1], v[2], v[3])
		{
			
		}
		
		/// <summary>
		/// Vertex3f constructor.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Single"/>
		/// </param>
		/// <param name="w">
		/// A <see cref="System.Single"/>
		/// </param>
		public Vertex4f(float x, float y, float z, float w)
		{
			this.x = x;
			this.y = y;
			this.z = z;
			this.w = w;
		}

		#endregion

		#region Structure

		/// <summary>
		/// X coordinate for fourdimensional vertex.
		/// </summary>
		public float x;

		/// <summary>
		/// Y coordinate for fourdimensional vertex.
		/// </summary>
		public float y;

		/// <summary>
		/// Z coordinate for fourdimensional vertex.
		/// </summary>
		public float z;

		/// <summary>
		/// W coordinate for fourdimensional vertex.
		/// </summary>
		public float w;
		
		#endregion

		#region Operators

		/// <summary>
		/// Transform vertex using transformation matrix.
		/// </summary>
		/// <param name="v">
		/// A <see cref="Vertex4f"/> that specifies the vertex to be transformed.
		/// </param>
		/// <param name="m">
		/// A <see cref="Matrix4x4"/> that specifies the transformation matrix.
		/// </param>
		/// <returns>
		/// It returns a <see cref="Vertex4f"/> which represents the transformed vertex.
		/// </returns>
		public static Vertex4f operator *(Vertex4f v, Matrix4x4 m)
		{
			Vertex4f r;

			r.x = (v.x * m[0,0]) + (v.y * m[1,0]) + (v.z * m[2,0]) + m[3,0];
			r.y = (v.x * m[0,1]) + (v.y * m[1,1]) + (v.z * m[2,1]) + m[3,1];
			r.z = (v.x * m[0,2]) + (v.y * m[1,2]) + (v.z * m[2,2]) + m[3,2];
			r.w = (v.x * m[0,3]) + (v.y * m[1,3]) + (v.z * m[2,3]) + m[3,3];

			return (r);
		}

		#endregion

		#region Cast

		/// <summary>
		/// 
		/// </summary>
		/// <param name="a"></param>
		/// <returns>
		/// </returns>
		public static implicit operator float[](Vertex4f a)
		{
			float[] v = new float[4];
			
			v[0] = a.x;
			v[1] = a.y;
			v[2] = a.z;
			v[3] = a.w;
			
			return (v);
		}
		
		/// <summary>
		/// Cast to Vertex2f operator.
		/// </summary>
		/// <param name="a">
		/// A <see cref="Vertex3f"/>
		/// </param>
		/// <returns>
		/// A <see cref="Vertex2f"/>
		/// </returns>
		public static implicit operator Vertex3f(Vertex4f a)
		{
			Vertex3f v;
			
			v.x = a.x / a.w;
			v.y = a.y / a.w;
			v.z = a.z / a.w;
			
			return (v);
		}
		
		#endregion

		#region IVertex4 Implementation
		
		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return (x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return (y); }
			set { y = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return (z); }
			set { z = value; }
		}

		/// <summary>
		/// Vertex coordinate w.
		/// </summary>
		public float W
		{
			get { return (w); }
			set { w = value; }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					case 3:
						return (W);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					case 3:
						W = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion

		#region Object Overrides

		/// <summary>
		/// Stringify this Vertex3f.
		/// </summary>
		/// <returns>
		/// Returns a <see cref="System.String"/> that represents this Vertex3f.
		/// </returns>
		public override string ToString()
		{
			return (String.Format("|{0}, {1}, {2}, {3}|", x, y, z, w));
		}

		#endregion
	}
	
	/// <summary>
	/// Homogeneous tridimensional vertex value type (double coordinates).
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	[ArrayBufferItem(VertexBaseType.Double, 4)]
	public struct Vertex4d : IVertex4
	{
		#region Structure

		/// <summary>
		/// X coordinate for fourdimensional vertex.
		/// </summary>
		public double x;

		/// <summary>
		/// Y coordinate for fourdimensional vertex.
		/// </summary>
		public double y;

		/// <summary>
		/// Z coordinate for fourdimensional vertex.
		/// </summary>
		public double z;

		/// <summary>
		/// W coordinate for fourdimensional vertex.
		/// </summary>
		public double w;

		#endregion

		#region IVertex4 Implementation

		/// <summary>
		/// Vertex coordinate X.
		/// </summary>
		public float X
		{
			get { return ((float)x); }
			set { x = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Y.
		/// </summary>
		public float Y
		{
			get { return ((float)y); }
			set { y = value; }
		}
		
		/// <summary>
		/// Vertex coordinate Z.
		/// </summary>
		public float Z
		{
			get { return ((float)z); }
			set { z = value; }
		}

		/// <summary>
		/// Vertex coordinate w.
		/// </summary>
		public float W
		{
			get { return ((float)w); }
			set { w = value; }
		}
		
		#endregion
		
		#region IVertex Implementation
		
		/// <summary>
		/// Vertex components indexer.
		/// </summary>
		/// <param name="idx">
		/// A <see cref="System.Int32"/> that specify the component index using for accessing to this IVertex component.
		/// </param>
		/// <remarks>
		/// <para>
		/// This indexer returns a single-precision floating-point representation of the vertex component value.
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="idx"/> is negative or exceed the maximum allowed component index.
		/// </exception>
		/// <exception cref="OverflowException">
		/// Exception thrown if the set value is outside the representable range of signed byte.
		/// </exception>s
		public float this[int idx]
		{
			get
			{
				switch (idx) {
					case 0:
						return (X);
					case 1:
						return (Y);
					case 2:
						return (Z);
					case 3:
						return (W);
					default:
						throw new ArgumentException("idx");
				}
			}
			set
			{ 
				switch (idx) {
					case 0:
						X = value;
						break;
					case 1:
						Y = value;
						break;
					case 2:
						Z = value;
						break;
					case 3:
						W = value;
						break;
					default:
						throw new ArgumentException("idx");
				}
			}
		}
		
		#endregion

		#region IXmlSerializable Implementation

		/// <summary>
		/// This property is reserved, apply the System.Xml.Serialization.XmlSchemaProviderAttribute to the class instead.
		/// </summary>
		/// <returns>
		/// It returns null.
		/// </returns>
		public XmlSchema GetSchema() { return (null); }

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		/// The System.Xml.XmlReader stream from which the object is deserialized.
		/// </param>
		public void ReadXml(XmlReader reader)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.ReadXml(reader, ref thisVertex);
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		/// The System.Xml.XmlWriter stream to which the object is serialized.
		/// </param>
		public void WriteXml(XmlWriter writer)
		{
			IVertex4 thisVertex = this;

			XmlVertexHelper.WriteXml(writer, ref thisVertex);
		}

		#endregion
	}
	
	#endregion

	#region IXmlSerializable Helper

	/// <summary>
	/// Class helping writing IXmlSerializable implementations
	/// </summary>
	class XmlVertexHelper
	{
		public static void ReadXml(XmlReader reader, ref IVertex2 vertex)
		{
			bool isEmpty = reader.IsEmptyElement;

			reader.ReadStartElement();

			string xValue = reader["X"];
			string yValue = reader["Y"];

			if (xValue != null)
				vertex.X = Single.Parse(xValue, NumberFormatInfo.InvariantInfo);
			if (yValue != null)
				vertex.Y = Single.Parse(yValue, NumberFormatInfo.InvariantInfo);

			if (isEmpty == false)
				reader.ReadEndElement();
		}

		public static void WriteXml(XmlWriter writer, ref IVertex2 vertex)
		{
			// Attribute: X coordinate
			writer.WriteAttributeString("X", vertex.X.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: Y coordinate
			writer.WriteAttributeString("Y", vertex.Y.ToString(NumberFormatInfo.InvariantInfo));

			// Example of output:
			//
			// <Vertex X="0.0" Y="0.0" />
		}

		public static void ReadXml(XmlReader reader, ref IVertex3 vertex)
		{
			bool isEmpty = reader.IsEmptyElement;

			reader.ReadStartElement();

			string xValue = reader["X"];
			string yValue = reader["Y"];
			string zValue = reader["Z"];

			if (xValue != null)
				vertex.X = Single.Parse(xValue, NumberFormatInfo.InvariantInfo);
			if (yValue != null)
				vertex.Y = Single.Parse(yValue, NumberFormatInfo.InvariantInfo);
			if (zValue != null)
				vertex.Z = Single.Parse(zValue, NumberFormatInfo.InvariantInfo);

			if (isEmpty == false)
				reader.ReadEndElement();
		}

		public static void WriteXml(XmlWriter writer, ref IVertex3 vertex)
		{
			// Attribute: X coordinate
			writer.WriteAttributeString("X", vertex.X.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: Y coordinate
			writer.WriteAttributeString("Y", vertex.Y.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: Z coordinate
			writer.WriteAttributeString("Z", vertex.Z.ToString(NumberFormatInfo.InvariantInfo));

			// Example of output:
			//
			// <Vertex X="0.0" Y="0.0" Z="0.0" />
		}

		public static void ReadXml(XmlReader reader, ref IVertex4 vertex)
		{
			bool isEmpty = reader.IsEmptyElement;

			reader.ReadStartElement();

			string xValue = reader["X"];
			string yValue = reader["Y"];
			string zValue = reader["Z"];
			string wValue = reader["W"];

			if (xValue != null)
				vertex.X = Single.Parse(xValue, NumberFormatInfo.InvariantInfo);
			if (yValue != null)
				vertex.Y = Single.Parse(yValue, NumberFormatInfo.InvariantInfo);
			if (zValue != null)
				vertex.Z = Single.Parse(zValue, NumberFormatInfo.InvariantInfo);
			if (wValue != null)
				vertex.W = Single.Parse(wValue, NumberFormatInfo.InvariantInfo);

			if (isEmpty == false)
				reader.ReadEndElement();
		}

		public static void WriteXml(XmlWriter writer, ref IVertex4 vertex)
		{
			// Attribute: X coordinate
			writer.WriteAttributeString("X", vertex.X.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: Y coordinate
			writer.WriteAttributeString("Y", vertex.Y.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: Z coordinate
			writer.WriteAttributeString("Z", vertex.Z.ToString(NumberFormatInfo.InvariantInfo));
			// Attribute: W coordinate
			writer.WriteAttributeString("W", vertex.W.ToString(NumberFormatInfo.InvariantInfo));

			// Example of output:
			//
			// <Vertex X="0.0" Y="0.0" Z="0.0" W="0.0" />
		}
	}

	#endregion
}
